package com.sharp.mq.config;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.AmqpIllegalStateException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.listener.adapter.InvocationResult;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.support.converter.MessageConverter;

/**
 * Title: MyMessageListenerAdapter
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2021/7/4 21:07
 */
public class MyMessageListenerAdapter extends MessageListenerAdapter {

    public MyMessageListenerAdapter(Object delegate, MessageConverter messageConverter) {
        super(delegate, messageConverter);
    }

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        Object delegateListener = this.getDelegate();
        if (delegateListener != this) {
            if (delegateListener instanceof ChannelAwareMessageListener) {
                ((ChannelAwareMessageListener) delegateListener).onMessage(message, channel);
                return;
            }

            if (delegateListener instanceof MessageListener) {
                ((MessageListener) delegateListener).onMessage(message);
                return;
            }
        }

        Object convertedMessage = this.extractMessage(message);
        String methodName = this.getListenerMethodName(message, convertedMessage);
        if (methodName == null) {
            throw new AmqpIllegalStateException("No default listener method specified: Either specify a non-null value for the 'defaultListenerMethod' property or override the 'getListenerMethodName' method.");
        } else {
            Object[] listenerArguments = this.buildListenerArguments(convertedMessage, message, channel);
            try {
                Object result = this.invokeListenerMethod(methodName, listenerArguments, message);
                if (result != null) {
                    this.handleResult(new InvocationResult(result, null, null, null, null), message, channel);
                } else {
                    this.logger.trace("No result object given - no result to handle");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    protected Object[] buildListenerArguments(Object extractedMessage, Message message, Channel channel) {
        return new Object[]{extractedMessage, message, channel};
    }
}
